package cn.water.luban.demo.order.main.consumer;

import cn.water.demo.luban.commons.exception.BusinessDemoException;
import cn.water.demo.luban.protocol.order.param.OrderAddParam;
import cn.water.luban.demo.order.main.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@RocketMQMessageListener(topic = "luban-order-topic",consumerGroup = "luban-order-group",selectorExpression = "*")
public class OrderConsumer implements RocketMQListener<OrderAddParam> {
    @Autowired
    private OrderService orderService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public void onMessage(OrderAddParam orderAddParam) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        //1.设计当前订单数据 的锁的key值和value
        String lockKey = "add:order:lock:"+orderAddParam.getOrderSn();
        String valueUuid = UUID.randomUUID().toString();
        //2 抢锁
        Boolean aBoolean = opsForValue.setIfAbsent(lockKey, valueUuid, 10, TimeUnit.SECONDS);
        try{
            //判断是否抢到锁
            while(!aBoolean){
                //没抢到
                Thread.sleep(5000);
                aBoolean = opsForValue.setIfAbsent(lockKey, valueUuid, 10, TimeUnit.SECONDS);
            }
            orderService.addOrder(orderAddParam);
            System.out.println("userId:"+orderAddParam.getUserId());
        }catch (BusinessDemoException | InterruptedException e){
            log.error("新增订单失败:"+e.getMessage(),e);
        }finally {
            //4.释放锁
            String value = opsForValue.get(lockKey);
            if(valueUuid.equals(value)){
                redisTemplate.delete(lockKey);
            }
        }

    }
}
